package org.ovirt.engine.core.bll;

import javax.inject.Inject;

import org.ovirt.engine.core.bll.context.EngineContext;
import org.ovirt.engine.core.bll.storage.ovfstore.OvfHelper;
import org.ovirt.engine.core.common.businessentities.OriginType;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.businessentities.VmEntityType;
import org.ovirt.engine.core.common.queries.GetVmFromOvaQueryParameters;
import org.ovirt.engine.core.common.vdscommands.GetOvaInfoParameters;
import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
import org.ovirt.engine.core.utils.ovf.OvfReaderException;

public class GetVmFromOvaQuery<T extends GetVmFromOvaQueryParameters> extends GetFromOvaQuery<VM, T> {

    @Inject
    private OvfHelper ovfHelper;

    public GetVmFromOvaQuery(T parameters, EngineContext engineContext) {
        super(parameters, engineContext);
    }

    protected VM parseOvf(String ovf) {
        boolean originOvirt = false;
        VM vm = null;

        try {
            originOvirt = ovf.contains("xmlns:ovirt");
            vm = readVmFromOva(ovf);
        } catch (Exception e) {
            if (originOvirt) {
                log.debug("failed to parse a given ovf configuration: \n" + ovf, e);
                getQueryReturnValue().setExceptionString("failed to parse a given ovf configuration " + e.getMessage());
            }
        }

        if (!originOvirt && vm == null) {
            // If we fail to parse an OVF that resides within an OVA generated by others,
            // let's try the old-way, using the minimal parsing of OVF in VDSM
            vm = getVmInfoFromOvaFile();
        }

        if (originOvirt && vm != null) {
            vm.setOrigin(OriginType.OVIRT);
        }

        return vm;
    }

    private VM getVmInfoFromOvaFile() {
        return (VM) runVdsCommand(VDSCommandType.GetOvaInfo, buildGetOvaInfoParameters()).getReturnValue();
    }

    private GetOvaInfoParameters buildGetOvaInfoParameters() {
        return new GetOvaInfoParameters(
                getParameters().getVdsId(),
                getParameters().getPath());
    }

    private VM readVmFromOva(String ovf) throws OvfReaderException {
        return ovf != null ? ovfHelper.readVmFromOva(ovf) : null;
    }

    @Override
    protected VmEntityType getEntityType() {
        return VmEntityType.VM;
    }
}
